/*
	post方式请求流数据
*/

// 定义ChatAi接口，用于传入参数
export interface ChatAi {
	url: string // 请求地址
	method?: string // 请求方式 默认post
	headers?: HeadersInit | undefined // 请求头
	data?: { [key: string]: any }
	isToJson?: boolean // 是否将数据转换为JSON格式 默认true
	isStream?: boolean // 是否流输出 默认true
	onOpen: (obj: AbortController) => void // 连接打开回调
	onMsg: (msg: any) => any // 消息回调
	onClose: (text: string) => void // 连接关闭回调
	onError: (error: string) => void // 错误回调
}

export async function chatAi(options: ChatAi) {
	// 解构传入的参数，设置默认值
	const { url, method = 'post', headers = {}, data, isToJson = true, isStream = true, onOpen, onMsg, onClose, onError } = options

	// 创建AbortController实例，用于中止请求
	const abortController = new AbortController()

	// 调用onOpen回调，表示连接已打开
	onOpen(abortController)

	// 发起fetch请求
	try {
		const res = await fetch(url, {
			method,
			headers,
			body: JSON.stringify(data), // 将数据转换为JSON字符串
			signal: abortController.signal, // 绑定中止信号
		})

		// 检查响应状态，如果失败则中止请求并调用错误回调
		console.log(res, 'res')
		if (!res.ok) {
			abortController.abort()
			onError(res.statusText)
			return
		}

		// 如果不是流输出，直接获取JSON数据并调用消息和关闭回调
		if(!isStream) {
			const json = await res.json()
      if(['0'].includes(String(json.code))){
        console.log(json, 'json')
        onMsg(json.data)
        onClose('ok')
      } else {
        onError(json.msg || '未知错误')	
      }
			return
		}

		// 获取可读流读取器
		const reader = res.body?.getReader()

		// 创建文本解码器
		const decoder = new TextDecoder('utf-8')

		// 如果无法获取读取器，中止请求并报错
		if (!reader) {
			abortController.abort()
			onError('读流失败')
			return
		}

		// 循环读取流数据
		while (true) {
			try {
				// 读取数据块
				const { done, value } = await reader.read()
				// 如果流结束，调用关闭回调并退出循环
				if (done) {
					onClose('ok')
					abortController.abort()
					break
				}
				// 解码数据块
				const chunk = decoder.decode(value)

				// 如果需要将数据转换为JSON格式，解析JSON数据
				const json = isToJson ? JSON.parse(chunk) : chunk

				// 调用消息回调，传递解码后的数据
				onMsg(json)
			} catch (e) {
				if (e instanceof Error && e.name === 'AbortError') {
					onClose('请求已被用户中止')
					break
				}
				console.log(e, 'while-catch')
			}
		}
	} catch (err) {
		if (err instanceof Error && err.name === 'AbortError') {
			onClose('请求已被用户中止')
		} else {
			onError(err instanceof Error ? err.message : '未知错误')
		}
	}
}
